fix(stall): thread retrieve_stall_seconds into send_to_fortress's retrieve too #38
+340
−12
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
ship_object's (size-routing) retrieve sharing the create-sideHTAR_STALL_SECONDS(2h) silence budget.send_to_fortress— the whole-target and Phase-3 leveled-incremental transport — carries its own, fully self-contained inline twin of the stall-watch logic (run_watched, invariant chore(reclaim): hold AAPF landing-zone raw until promote loop verified #1: no outer-scope references so it stays safe under--globus) and was left on its own hardcoded 7200s default for both the create step and the two retrieve steps (hsi get, then localtar xvf).repository_X0H_2_spectral-standoff(job 41417829, 2026-07-31, a leveled-incremental, multi-TB whole-target tar): create succeeded, then the round-trip retrieve was killed at exactly "no output for 2.0h" — the same bug class PR fix(stall): bound the verify retrieve separately from the create (X1D re-ship loop) #37 fixed for the routed path.send_to_fortressnow takesretrieve_stall_secondsand requires it (raises before anyhtar_large/hsi/tarcall) — mirroringship_object's contract exactly, no code-side fallback that could silently reinstate the 2h bound.run_watched()calls (hsi get,tar xvf); the create call is untouched (still the hardcoded 7200s default — a create streams per-file progress, so silence there really is a hang).ship_level) updated to pass the already-loaded config value through positionally (runonly forwards positional args).stall_defaults.json's existingretrieve_stall_secondsdefault/config key rather than adding a second knob — it was already documented path-agnostically ("the post-create round-trip verify retrieve"). An operator can still raise it per-asset for X0H-sized multi-TB tars via the same override mechanism that already exists. Happy to split this into a separate default if review disagrees.CLAUDE.md,stall_defaults.json, andconfig.example.jsoncomments updated to reflect both transports sharing this one bound.Test plan
tests/test_send_to_fortress_retrieve_stall.py: fakeshtar_large/hsi/taras shell-script stand-ins onPATH(matchingtest_ship_object_htar_rc.py's approach), sincerun_watchedis a closure local tosend_to_fortressand can't be intercepted the wayarchive._run_with_stall_watchis forship_object. Each behavioral assertion runssend_to_fortresson a background thread with a boundedjoin()so a regression that falls back to the 2h default fails fast (not a real 2-hour hang).hsi getretrieve honors the configured bound, not the 2h defaulttar xvfretrieve honors the configured bound, not the 2h defaultretrieve_stall_secondsraises before any tape workNot merging or deploying — flagging for review per usual process.
🤖 Generated with Claude Code